package com.oceansoft.mobile.econsole.modules.expireWarn.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.oceansoft.mobile.econsole.cache.redis.CacheBaseService;
import com.oceansoft.mobile.econsole.common.constant.Constant;
import com.oceansoft.mobile.econsole.common.util.HttpClientUtil;
import com.oceansoft.mobile.econsole.common.util.encrypt.DesAPPUtils;
import com.oceansoft.mobile.econsole.modules.expireWarn.persistence.ExpireWarnMapper;
import com.oceansoft.mobile.econsole.modules.expireWarn.service.ExpireWarnService;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.AppMessage;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.ExpireWarnQueryEntity;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.InQueryServiceInfo;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.InQueryServiceInfoAtt;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.OutQueryServiceInfo;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.OutQueryServiceInfo2;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.SMSMessage;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.WechatMessage;
import com.oceansoft.mobile.econsole.modules.jlapi.persistence.IJlApiInfoMapper;
import com.oceansoft.mobile.econsole.modules.member.entity.WtMember;
import com.oceansoft.mobile.econsole.modules.member.persistence.IWtMemberMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
 * ClassName: ExpireWarnServiceImpl
 * Desc: 过期提醒定业务实现类
 * Date： 2016/11/7
 * Created：shaom
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ExpireWarnServiceImpl extends CacheBaseService implements ExpireWarnService {

    private static final Logger logger = LoggerFactory.getLogger(ExpireWarnServiceImpl.class);

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private ExpireWarnMapper expireWarnMapper;

    @Resource
    private IJlApiInfoMapper jlApiInfoMapper;

    @Resource
    private IWtMemberMapper wtMemberMapper;

    @Override
    public void pushMsg(InQueryServiceInfo inInfo) {
        threadPoolTaskExecutor.execute(new InThread(inInfo));
    }

    @Override
    public void pushMsg(final List<ExpireWarnQueryEntity> inInfos) {
        threadPoolTaskExecutor.execute(new SendThread(inInfos));
    }

    @Override
    public List<ExpireWarnQueryEntity> getiDCardExpireQuery() {
        List<ExpireWarnQueryEntity> lists = Lists.newArrayList();
        List<WtMember> members = expireWarnMapper.getEffectiveMember();
        if (members.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        for (WtMember member : members) {
            ExpireWarnQueryEntity expireWarn = new ExpireWarnQueryEntity();
            try {
                expireWarn.setUserCode(DesAPPUtils.decrypt(member.getUserCode()));//身份证
            } catch (Exception e) {
                logger.info("身份证解码失败!!");
                continue;
            }
            expireWarn.setMobile(member.getUserName());// 手机
            expireWarn.setOpenId(member.getWeixinid());// 微信
            lists.add(expireWarn);
        }
        return lists;
    }

    @Override
    public List<ExpireWarnQueryEntity> getVehicleExpireWarnQuery() {
        List<ExpireWarnQueryEntity> lists = Lists.newArrayList();
        List<WtMember> members = expireWarnMapper.getEffectiveVehicleMember();
        if (members.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        for (WtMember member : members) {
            ExpireWarnQueryEntity expireWarn = new ExpireWarnQueryEntity();
            try {
                expireWarn.setUserCode(DesAPPUtils.decrypt(member.getUserCode()));//身份证
            } catch (Exception e) {
                logger.info("身份证解码失败!!");
                continue;
            }
            expireWarn.setMobile(member.getUserName());// 手机
            expireWarn.setOpenId(member.getWeixinid());// 微信
            lists.add(expireWarn);
        }
        return lists;
    }

    @Override
    public List<ExpireWarnQueryEntity> getTodayExpireData(String action) {
        List<ExpireWarnQueryEntity> lists = Lists.newArrayList();
        List<OutQueryServiceInfo> todayExpireData = expireWarnMapper.getTodayExpireData(action);
        if (todayExpireData.isEmpty()) {
            return Collections.emptyList();//直接返回
        }

        for (OutQueryServiceInfo outInfo : todayExpireData) {
            String res = outInfo.getRes();
            if (Strings.isNullOrEmpty(res)) {
                logger.info("返回数据为空，不发送提醒!!");
                continue;
            }
            ExpireWarnQueryEntity expireWarn = JSON.parseObject(res, ExpireWarnQueryEntity.class);
            String mobile = expireWarn.getMobile();
            if (Strings.isNullOrEmpty(mobile)) {
                logger.info("手机号码为空，不发送提醒!!");
                continue;
            }
            expireWarn.setAction(action);
            WtMember wtMember = wtMemberMapper.getInfoByUserName(mobile);
            if (!Objects.isNull(wtMember) && !Strings.isNullOrEmpty(wtMember.getWeixinid())) {
                expireWarn.setOpenId(wtMember.getWeixinid());// 微信
            }
            lists.add(expireWarn);
        }

        return lists;
    }

    @Override
    public List<ExpireWarnQueryEntity> getTodayExpireAttData(String action) {

        List<ExpireWarnQueryEntity> lists = Lists.newArrayList();
        List<OutQueryServiceInfo> todayExpireData = expireWarnMapper.getTodayExpireData(action);
        if (todayExpireData.isEmpty()) {
            return Collections.EMPTY_LIST;//直接返回
        }

        for (OutQueryServiceInfo outInfo : todayExpireData) {
            List<OutQueryServiceInfo2> outQueryServiceInfos = jlApiInfoMapper.queryListOutServiceInfo2(outInfo.getSn());
            for (OutQueryServiceInfo2 attInfo : outQueryServiceInfos) {
                String res = attInfo.getRes();
                if (Strings.isNullOrEmpty(res)) {
                    logger.info("返回数据为空，不发送提醒!!");
                    continue;
                }

                ExpireWarnQueryEntity expireWarn = JSON.parseObject(res, ExpireWarnQueryEntity.class);
                String mobile = expireWarn.getMobile();
                if (Strings.isNullOrEmpty(mobile)) {
                    logger.info("手机号码为空，不发送提醒!!");
                    continue;
                }
                expireWarn.setAction(action);
                WtMember wtMember = wtMemberMapper.getInfoByUserName(mobile);
                if (!Objects.isNull(wtMember) && !Strings.isNullOrEmpty(wtMember.getWeixinid())) {
                    expireWarn.setOpenId(wtMember.getWeixinid());// 微信
                }
                lists.add(expireWarn);
            }
        }
        return lists;
    }


    /**
     * 业务处理线程
     */
    private class InThread implements Runnable {

        private InQueryServiceInfo inInfo;

        public InThread(InQueryServiceInfo inInfo) {
            this.inInfo = inInfo;
        }

        @Override
        public void run() {
            logger.info(inInfo.getAction() + " +++ 开始业务线程 ++++");

            // 1-直接去保存IN表数据
            this.saveIN(inInfo);
            try {
                Thread.sleep(10000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 2-开始OUT表的查询
            int searchCount;
            OutQueryServiceInfo outInfo = null;
            for (searchCount = 0; searchCount < 9; searchCount++) {// TODO 修改为 9
                List<OutQueryServiceInfo> outQueryServiceInfos = jlApiInfoMapper.queryListOutServiceInfo(inInfo.getSn());
                if (!Objects.isNull(outQueryServiceInfos) && !outQueryServiceInfos.isEmpty()) {
                    outInfo = outQueryServiceInfos.get(0);
                }

                if (!Objects.isNull(outInfo) && Objects.equals("Y", outInfo.getSucc())) {
                    // 查询结果获取成功且成功查询出所需信息，退出轮训
                    break;
                }

                try {
                    Thread.sleep(10000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // 3-开始推送
            if (!Objects.isNull(outInfo) && Objects.equals("Y", outInfo.getSucc())) {
                // 3-1 查询OUT-ATT表的数据
                List<OutQueryServiceInfo2> outQueryServiceInfos = jlApiInfoMapper.queryListOutServiceInfo2(outInfo.getSn());
                for (OutQueryServiceInfo2 queryServiceInfo : outQueryServiceInfos) {
                    // 3-2 推送
                    String res = queryServiceInfo.getRes();
                    if (Strings.isNullOrEmpty(res)) {
                        logger.info("返回的OUT-ATT表数据为空！");
                        continue;
                    }
                    this.push(queryServiceInfo);
                }

            } else {
                logger.info(inInfo.getAction() + " ++++ 没有查到OUT返回的数据 ++++" + inInfo.getSn());
            }

            logger.info(inInfo.getAction() + " +++  业务线程结束  ++++");
        }

        /**
         * 保存IN表数据(IN和IN-ATT)
         *
         * @param inInfo
         */
        private void saveIN(InQueryServiceInfo inInfo) {
            List<String> lists = JSON.parseArray(inInfo.getCommand(), String.class);
            inInfo.setCommand(" ");//置空

            for (String entity : lists) {
                InQueryServiceInfoAtt inAtt = new InQueryServiceInfoAtt().build(inInfo);
                inAtt.setGuid(UUID.randomUUID().toString().replace("-", ""));
                inAtt.setCommand(entity);

                jlApiInfoMapper.insertInAtt(inAtt);
            }
            jlApiInfoMapper.insertInServiceInfo(inInfo);
        }

        /**
         * 推送
         *
         * @param queryServiceInfo OUT表返回的数据
         */
        private void push(OutQueryServiceInfo2 queryServiceInfo) {
            String type = "";
            String content = "";
            String action = queryServiceInfo.getAction();// 判断显示推送信息
            ExpireWarnQueryEntity entity = JSON.parseObject(queryServiceInfo.getRes(), ExpireWarnQueryEntity.class);

            if (Objects.equals(InQueryServiceInfo.API_011, action)) {
                type = "身份证到期提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_IC, entity.getExpireDate());
            } else if (Objects.equals(InQueryServiceInfo.API_012, action)) {
                type = "驾驶证到期提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_VL, entity.getExpireDate());
            } else if (Objects.equals(InQueryServiceInfo.API_013, action)) {
                type = "年检到期提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_AC, entity.getHphm(), entity.getExpireDate());
            }

            // APP
            AppMessage appMessage = new AppMessage();
            appMessage.setReceiver(entity.getMobile());// 前端商量
            appMessage.setMsgType(AppMessage.MessageType.VEHICLE_BIND);
            appMessage.setTitle(type);
            appMessage.setContent(content);

            Map<String, String> map = Maps.newHashMap();
            map.put("guid", queryServiceInfo.getGuid());
            map.put("sn", queryServiceInfo.getSn());
            appMessage.setExtra(map);
            HttpClientUtil.doPostString(configInfo.getAppSendUrl(), appMessage);

            // 微信
            String openId = entity.getOpenId();
            if (!Strings.isNullOrEmpty(openId)) {
                WechatMessage wechatMessage = new WechatMessage();
                wechatMessage.setOpenId(openId);
                wechatMessage.setTempId(WechatMessage.WECHAT_TEMPLATEID);

                HashMap<String, String[]> keyMap = new HashMap<>();
                keyMap.put("first", new String[]{content, "#173177"});
                keyMap.put("keyword1", new String[]{type, "#173177"});
                keyMap.put("keyword2", new String[]{entity.getExpireDate(), "#173177"});
                wechatMessage.setParams(keyMap);
                HttpClientUtil.doPostString(configInfo.getWechatSendUrl(), wechatMessage);
            }

            // 短信
            SMSMessage smsMessage = new SMSMessage();
            smsMessage.setReceiver(entity.getMobile());
            smsMessage.setContent(content);
            HttpClientUtil.doPostString(configInfo.getSmsSendUrl(), smsMessage);
        }
    }


    private class SendThread implements Runnable {

        private final List<ExpireWarnQueryEntity> expireEntities;

        public SendThread(List<ExpireWarnQueryEntity> expireEntities) {
            this.expireEntities = expireEntities;
        }

        @Override
        public void run() {
            for (ExpireWarnQueryEntity expireEntity : expireEntities) {
                sendMsg(expireEntity);
            }
        }


        private void sendMsg(ExpireWarnQueryEntity expireEntity) {
            logger.info("+++++++++++++ 发送短信 START +++++++++++++++++++");

            String type = "";
            String content = "";
            String action = expireEntity.getAction();// 判断显示推送信息

            if (Objects.equals(InQueryServiceInfo.API_011, action)) {
                type = "身份证到期提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_IC, expireEntity.getExpireDate());
            } else if (Objects.equals(InQueryServiceInfo.API_012, action)) {
                type = "驾驶证到期提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_VL, expireEntity.getExpireDate());
            } else if (Objects.equals(InQueryServiceInfo.API_013, action)) {
                type = "年检到期提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_AC, expireEntity.getHphm(), expireEntity.getExpireDate());
            } else if (Objects.equals(InQueryServiceInfo.API_014, action)) {
                type = "违章提醒";
                content = String.format(Constant.EXPIRE_WARN_MSG_VV, expireEntity.getHphm(), expireEntity.getWfsj(), expireEntity.getWfdz());
            }

            // APP
            AppMessage appMessage = new AppMessage();
            appMessage.setReceiver(expireEntity.getMobile());// 前端商量
            appMessage.setMsgType(AppMessage.MessageType.VEHICLE_BIND);
            appMessage.setTitle(type);
            appMessage.setContent(content);
            HttpClientUtil.doPostString(configInfo.getAppSendUrl(), appMessage);

            // 微信
            String openId = expireEntity.getOpenId();
            if (!Strings.isNullOrEmpty(openId)) {
                WechatMessage wechatMessage = new WechatMessage();
                wechatMessage.setOpenId(openId);
                wechatMessage.setTempId(WechatMessage.WECHAT_TEMPLATEID);

                HashMap<String, String[]> keyMap = new HashMap<>();
                keyMap.put("first", new String[]{content, "#173177"});
                keyMap.put("keyword1", new String[]{type, "#173177"});
                keyMap.put("keyword2", new String[]{expireEntity.getExpireDate(), "#173177"});
                wechatMessage.setParams(keyMap);
                HttpClientUtil.doPostString(configInfo.getWechatSendUrl(), wechatMessage);
            }

            logger.info("+++++++++++++ 发送短信 END +++++++++++++++++++");

        }

    }
}
